package EA.testproblems;
import EA.*;
import RKUjava.util.*;

/**
This testproblem was used in the initial patchwork paper by Krink, Mayoh, Michalewicz. <br><br>

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Krink F1</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">Waves (several peaks)&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Provides a very spiky maximization task</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">(50-|x-50|+40sin(5/18 pi x))+(50-|y-50|+40sin(5/18 pi y))</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/krinkf1.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/krinkf1_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [0:100]&nbsp;&nbsp;y = [0:100] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Maximization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maxima:</b></td>
  <td valign="top">several</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minima:</b></td>
  <td valign="top">several</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optima radius:</b></td>
  <td valign="top">unknown
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optima descriptions:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optima:</b></td>
  <td valign="top">
  LMAX(52.167,52.167); MaxFitness(175.63284)

<br><font size=1>Capital letters 
means that the precise optima is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 40<br>
  set view 70,15<br>
splot [0:100] [0:100] (50-abs(x-50)+40*sin((5*pi*x)/18))+(50-abs(y-50)+40*sin((5*pi*y)/18))
</td>
</tr>
   <tr bgcolor="#e0e0e0">
   <td valign="top"><b>Latex code:</b></td>
   <td valign="top">
   Krink F1:<br>
   \begin{eqnarray*}<br>
   f(x,y) &=& 50-\|{}x-50\|{} + 40sin\left(\frac{5\pi\cdot{}x}{18}\right) + \\<br>
   &&50-\|{}y-50\|{} + 40sin\left(\frac{5\pi\cdot{}y}{18}\right)\\[-2mm]<br>
   \end{eqnarray*}<br>
   where\\<br>
   \vspace*{-2mm}<br>
   \[<br>
   0\leq{}x\leq{}100 \; \textrm{ and }0\leq{}y\leq{}100 <br>
   \]<br>
   </td></tr>
</table>
*/

public class KrinkF1 extends NumericalProblem 
{

  // Easier way to build max and min
    private double[][] lmax = {{52.167,52.167}};
    private double[][] lmin = {{0,0}};

  public KrinkF1()
    {
      super();

      double[] optima;

      name = "Krink F1";
      objectivefunction = new NumericalFitness(){
	public double Fitness_calcFitness_inner(double[] realpos)
	{
	  //  System.out.println ((50.0-Math.abs(52.167-50.0)+40.0*Math.sin((5.0/18.0)*Math.PI*52.167)) +
	  //                      (50.0-Math.abs(52.167-50.0)+40.0*Math.sin((5.0/18.0)*Math.PI*52.167)));
	  //	  System.out.println("ad"+RKUStringUtils.arrayToString(realpos)+" fit="+(100*(Math.pow(((realpos[0]*realpos[0]) - realpos[1]),2)) + Math.pow((1-realpos[0]),2)));
	  return (50.0-Math.abs(realpos[0]-50.0)+40.0*Math.sin((5.0*Math.PI*realpos[0])/18.0)) +
	         (50.0-Math.abs(realpos[1]-50.0)+40.0*Math.sin((5.0*Math.PI*realpos[1])/18.0));
	};
      };

      dimensions = 2;
      ismaximization = true;
      optimumradius = 0.2;

      intervals = new Interval[2];
      intervals[0] = new Interval(0, 100);
      intervals[1] = new Interval(0, 100);

      
      // Set up known maxima
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optima = new double[dimensions];
	optima[0] = lmax[i][0];
	optima[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optima, objectivefunction.calcFitness(optima), true, false, i);
      }

      // Set up known minima
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optima = new double[dimensions];
	optima[0] = lmin[i][0];
	optima[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optima, objectivefunction.calcFitness(optima), false, false, i);
      }

    }
}
